import { getPermission, admin } from "@/utils/constant"
import storeInstance from "@/pinia"
import router from "@/router"
import { getMd5 } from '@/utils/tools'

export default function (app) {
    app.directive("permission", {
        mounted(el, binding) {
            const o = binding.modifiers["&"] ? "and" : "or"
            const modifierPermission = Object.keys(binding.modifiers).map(e => getPermission(e)).filter(e => e)
            const permission = usePermission(binding.value ? binding.value : bitwiseOperation(modifierPermission, operate[o]))
            if (!permission && el) el.remove()
        }
    })
}

const operate = { or: (a, b) => a | b, and: (a, b) => a & b }

const bitwiseOperation = (arr, operator) => {
    return arr.reduce((result, num) => {
        return result === null ? num : operator(result, num)
    }, null)
}

export const usePermission = (v_permission) => {
    try {
        //获取用户信息
        const userInfo = storeInstance.userStore.getUserInfo
        if (userInfo.role === admin.role) return true
        //获取用户路由信息，包括目录集合，权限集合，路由集合
        const routeInfo = storeInstance.userStore.getRouteInfo
        //获取路由列表
        const route = routeInfo.router.map(e => e.url)
        if (typeof v_permission === 'boolean') {
            return v_permission
        }
        if (typeof v_permission === 'function') {
            return v_permission()
        }
        if (v_permission === null || v_permission === undefined) {
            return false
        }
        //整合权限参数
        const permissionInfo = typeof v_permission === 'number' ? { permission: v_permission, url: '' }
            : typeof v_permission === 'string' ? { permission: 0, url: v_permission } : v_permission
        const { permission, url } = permissionInfo
        if (!permission && !url) return false
        //获取当前路由权限
        const routePermission = routeInfo.permission[getMd5(router.currentRoute.value.path)]
        //判断根据传入的权限参数分别判断权限和url，合并是否有权限
        const hasPermission = ((permission ? (routePermission & permission) : true) && (url ? route.includes(url) : true))
        if (!hasPermission) {
            return false
        }
        return true
    } catch (error) {
        console.error(error)
        return false
    }
}
